package com.ly.common;

import org.springframework.web.multipart.MultipartFile;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Documented
@Constraint(
        validatedBy = {FileNotEmpty.FileNotEmptyValidator.class, FileNotEmpty.FilesNotEmptyValidator.class}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FileNotEmpty {
    /**
     * Message string.
     *
     * @return the string
     */
    String message() default "文件格式不正确";

    /**
     * 校验组
     *
     * @return the class [ ]
     */
    Class<?>[] groups() default {};

    /**
     * Payload class [ ].
     *
     * @return the class [ ]
     */
    Class<? extends Payload>[] payload() default {};

    /**
     * 需要校验的格式数组
     *
     * @return the string [ ]
     */
    String[] format() default {};

    /**
     * 是否必填 为false时文件为空则不校验格式，不为空则校验格式
     * 为true时文件不能为空且需要验证格式
     *
     * @return the boolean
     */
    boolean required() default true;

    /**
     * 单文件校验
     *
     * @author gwq
     * @version 1.0
     * @date 2022 -6-20
     */
    public class FileNotEmptyValidator implements ConstraintValidator<FileNotEmpty, MultipartFile> {
        private Set<String> formatSet = new HashSet<>();
        private boolean required;

        @Override
        public void initialize(FileNotEmpty constraintAnnotation) {
            String[] format = constraintAnnotation.format();
            this.formatSet = new HashSet<>(Arrays.asList(format));
            this.required = constraintAnnotation.required();
        }

        @Override
        public boolean isValid(MultipartFile multipartFile, ConstraintValidatorContext constraintValidatorContext) {
            if (multipartFile == null || multipartFile.isEmpty()) {
                return !required;
            }
            String originalFilename = multipartFile.getOriginalFilename();
            assert originalFilename != null;
            String type = originalFilename.substring(originalFilename.lastIndexOf('.') + 1).toLowerCase();
            if (!formatSet.isEmpty()) {
                return formatSet.contains(type);
            }
            return true;
        }
    }

    /**
     * 多文件校验
     *
     * @author gwq
     * @version 1.0
     * @date 2022 -6-20
     */
    public class FilesNotEmptyValidator implements ConstraintValidator<FileNotEmpty, MultipartFile[]> {
        private Set<String> formatSet = new HashSet<>();
        private boolean required;

        @Override
        public void initialize(FileNotEmpty constraintAnnotation) {
            String[] format = constraintAnnotation.format();
            this.formatSet = new HashSet<>(Arrays.asList(format));
            this.required = constraintAnnotation.required();
        }

        @Override
        public boolean isValid(MultipartFile[] multipartFiles, ConstraintValidatorContext constraintValidatorContext) {
            if (multipartFiles == null || multipartFiles.length == 0) {
                return !required;
            }
            for (MultipartFile file : multipartFiles) {
                String originalFilename = file.getOriginalFilename();
                assert originalFilename != null;
                String type = originalFilename.substring(originalFilename.lastIndexOf('.') + 1).toLowerCase();
                if (formatSet.isEmpty() || !formatSet.contains(type)) {
                    return false;
                }
            }
            return true;
        }
    }
}